//
//  MainView.swift
//  GuMro
//
//  Created by mac on 2019/12/4.
//  Copyright © 2019 cn.gomro.app. All rights reserved.
//

import UIKit
import Charts

class MainView: BaseView {
    
    var viewModel:MainViewModel?
    private lazy var arrChartData = [[String:Any]]()
    private let timeInterval = TimeInterval.init(1.0)
    
    
    //MARK: - override
    override init(ViewModel vm: ViewModelProtocol) {
        self.viewModel = vm as? MainViewModel
        super.init(ViewModel: vm)
        
        //加载分时
        self.viewModel?.loadFSDataCommand.execute(true)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func setupViews() {
        self.addSubview(self.segView)
        
        setNeedsUpdateConstraints()
    }
    
    override func updateConstraints() {
        
        self.segView.snp.makeConstraints { make in
            make.top.equalTo(Setting.K_APP_SAFETY_NAV_HEIGHT + 2)
            make.width.equalTo(180)
            make.height.equalTo(40)
            make.left.equalTo((Setting.K_APP_WIDTH - 180) * 0.5)
        }
        
        super.updateConstraints()
    }
    
    override func bindViewModel() {
        
        self.viewModel?.loadFSDataCommand.executionSignals.switchToLatest()?.subscribeNext({[unowned self] (input:Any?) in
            if let _arrTemp = input as? [[String:Any]],_arrTemp.count > 0 {
                self.arrChartData = _arrTemp
            }
            
            DispatchQueue.main.async {
                if self.typeIndex == 0 {
                    self.combineLineChare.removeFromSuperview()
                    
                    self.addSubview(self.lineChare)
                    self.lineChare.snp.makeConstraints { make in
                        make.top.equalTo(Setting.K_APP_NAVIGATION_BAR_HEIGHT)
                        make.width.equalTo(Setting.K_APP_WIDTH)
                        make.height.equalTo(300)
                        make.left.right.equalTo(0)
                    }
                    
                    self.setLineData(isChange: true)
                }
                else{
                    self.lineChare.removeFromSuperview()
                    
                    self.addSubview(self.combineLineChare)
                    self.combineLineChare.snp.makeConstraints { make in
                        make.top.equalTo(Setting.K_APP_NAVIGATION_BAR_HEIGHT)
                        make.width.equalTo(Setting.K_APP_WIDTH)
                        make.height.equalTo(300)
                        make.left.right.equalTo(0)
                    }
                    
                    self.setCombineLineData(isChange: true)
                }
            }
        })
        
    }
    
    
    //MARK: - lazy load
    private lazy var typeIndex:Int = 0
    
    private lazy var segView:UISegmentedControl = {[weak self] in
        let _seg = UISegmentedControl.init(items: ["分时","分时二"])
        _seg.selectedSegmentIndex = 0
        _seg.tintColor = Setting.K_APP_TINT_COLOR
        _seg.addTarget(self,
                       action: #selector(segValueChange(sender:)),
                       for: .valueChanged)
        
        return _seg
    }()
    
    
    /// 单折线
    private lazy var lineChare:LineChartView = {[weak self] in
        autoreleasepool {
            let _chart = LineChartView.init()
            _chart.delegate = self
            _chart.legend.form = .line
            _chart.maxVisibleCount = 29
            
            //禁止双击缩放 有需要可以设置为YES
            _chart.doubleTapToZoomEnabled = true
            
            //表框以及表内线条的颜色以及隐藏设置 根据自己需要调整
            _chart.gridBackgroundColor = UIColor.white
            
            _chart.borderColor = UIColor.init(hexString: "#B5B5B5")!
            
            _chart.drawGridBackgroundEnabled = false
            
            //边框
            _chart.drawBordersEnabled = false
            
            //是否显示折线的名称以及对应颜色
            _chart.legend.enabled = false
            
            //暂无数据
            _chart.noDataText = "暂无数据"
            _chart.noDataTextColor = UIColor.lightGray
            
            //[S]纵轴内边框线
            _chart.xAxis.gridLineDashLengths = [5.0, 5.0]
            _chart.xAxis.gridLineDashPhase = 0
            
            _chart.xAxis.drawGridLinesEnabled = true
            _chart.xAxis.drawLimitLinesBehindDataEnabled = true
            
            //设置横轴坐标显示在下方 默认显示是在顶部
            _chart.xAxis.labelPosition = .bottom
            _chart.xAxis.labelTextColor = UIColor.init(hexString: "#C6C6C6")!
            
            //避免文字显示不全 这个属性很重要
            _chart.xAxis.avoidFirstLastClippingEnabled = true
            //设置最多显示点数
            //_chart.xAxis.axisMaximum = 80
            _chart.xAxis.axisMinimum = 0
            //[E]
            
            //折线名称字体颜色
            //_chart.legend.textColor = UIColor.init(hexString: "#4BD863")!
            
            //设置动画时间
            _chart.animate(xAxisDuration: timeInterval)
            
            //[S]设置纵轴坐标显示在右边而非左边
            _chart.rightAxis.enabled = true
            _chart.leftAxis.enabled = false
            
            //横轴刻度
            _chart.rightAxis.gridLineDashLengths = [5.0, 5.0]
            _chart.rightAxis.gridLineDashPhase = 0
            
            _chart.rightAxis.drawGridLinesEnabled = true
            _chart.rightAxis.drawZeroLineEnabled = true
            
            _chart.rightAxis.drawLimitLinesBehindDataEnabled = true
            _chart.rightAxis.labelTextColor = UIColor.init(hexString: "#8B8B8B")!
            //[E]
            
            //[S]显示自定义浮层
            _chart.drawMarkers = true
            //[E]
            
            return _chart
        }
    }()
    
    
    /// 混合折线图
    private lazy var combineLineChare:CombinedChartView = {[weak self] in
        autoreleasepool {
            let _ccv = CombinedChartView.init()
            _ccv.delegate = self
            
            //绘制顺序
            _ccv.drawOrder = [2]
            
            //禁止双击缩放 有需要可以设置为YES
            _ccv.doubleTapToZoomEnabled = true
            
            //表框以及表内线条的颜色以及隐藏设置 根据自己需要调整
            _ccv.gridBackgroundColor = UIColor.white
            
            _ccv.borderColor = UIColor.init(hexString: "#B5B5B5")!
            
            _ccv.drawGridBackgroundEnabled = false
            
            //边框
            _ccv.drawBordersEnabled = false
            
            //是否显示折线的名称以及对应颜色
            _ccv.legend.enabled = false
            
            //暂无数据
            _ccv.noDataText = "暂无数据"
            _ccv.noDataTextColor = UIColor.lightGray
            
            //[S]纵轴内边框线
            _ccv.xAxis.gridLineDashLengths = [5.0, 5.0]
            _ccv.xAxis.gridLineDashPhase = 0
            
            _ccv.xAxis.drawGridLinesEnabled = true
            _ccv.xAxis.drawLimitLinesBehindDataEnabled = true
            
            //设置横轴坐标显示在下方 默认显示是在顶部
            _ccv.xAxis.labelPosition = .bottom
            _ccv.xAxis.labelTextColor = UIColor.init(hexString: "#C6C6C6")!
            
            //避免文字显示不全 这个属性很重要
            _ccv.xAxis.avoidFirstLastClippingEnabled = true
            //设置最多显示点数
            //_ccv.xAxis.axisMaximum = 15
            _ccv.xAxis.axisMinimum = 0
            //[E]
            
            //折线名称字体颜色
            //_ccv.legend.textColor = UIColor.init(hexString: "#4BD863")!
            
            //设置动画时间
            _ccv.animate(xAxisDuration: timeInterval)
            
            //[S]设置纵轴坐标显示在右边而非左边
            _ccv.rightAxis.enabled = true
            _ccv.leftAxis.enabled = false
            
            //横轴刻度
            _ccv.rightAxis.gridLineDashLengths = [5.0, 5.0]
            _ccv.rightAxis.gridLineDashPhase = 0
            
            _ccv.rightAxis.drawGridLinesEnabled = true
            _ccv.rightAxis.drawZeroLineEnabled = true
            
            _ccv.rightAxis.drawLimitLinesBehindDataEnabled = true
            _ccv.rightAxis.labelTextColor = UIColor.init(hexString: "#8B8B8B")!
            //[E]
            
            //[S]显示自定义浮层
            _ccv.drawMarkers = true
            //[E]
            
            return _ccv
        }
    }()
    
    //点击浮层
    private lazy var xyMarkView:XYMarkerView = {
        let _xym = XYMarkerView.init(color: UIColor.init(hexString: "#E5F1FC")!,//背景色
                                     font: UIFont.systemFont(ofSize: 12),
                                     textColor: UIColor.init(hexString: "#333333")!,
                                     insets: UIEdgeInsets.init(top: 8, left: 8, bottom: 20, right: 8),
                                     xAxisValueFormatter: self.lineChare.xAxis.valueFormatter!)
        
        _xym.minimumSize = CGSize.init(width: 80, height: 40)
        return _xym
    }()
}


//MARK: - MainView
extension MainView {
    
    //MARK: - 值改变
    /// 值改变
    /// - Parameter sender: sender description
    @objc private func segValueChange(sender:UISegmentedControl){
        
        if sender.selectedSegmentIndex == self.typeIndex { return }
        
        self.typeIndex = sender.selectedSegmentIndex
        self.viewModel?.loadFSDataCommand.execute(true)
    }
    
    
    //MARK: - 单分时
    /// 单分时
    /// - Parameter isChange: Bool
    private func setLineData(isChange:Bool = false) {
        if arrChartData.count > 0 {
            //x、y轴数据
            var xValues = [String]()
            var entry:ChartDataEntry?
            var yValue = [ChartDataEntry]()
            
            var i = 0
            for item in arrChartData {
                let _dateTime:UInt32 = item["UpdateTime"] as! UInt32
                let _strDateTime = Utils.shareInstance().getDateTimeForUnix(unixTime: _dateTime, strFormat: "HH:mm")
                xValues.append(_strDateTime)
                
                entry = ChartDataEntry.init(x: Double.init(i),
                                            y: Double.init("\(item["Open"] ?? "0.000")")!)
                yValue.append(entry!)
                i += 1
            }
            
            if xValues.count > 0 {
                self.lineChare.xAxis.valueFormatter = IndexAxisValueFormatter.init(values: xValues)
            }
            
            //创建LineChartDataSet对象
            let picketageSet = LineChartDataSet.init(entries: yValue, label: "")
            
            //十字线
            picketageSet.drawHorizontalHighlightIndicatorEnabled = false
            picketageSet.drawVerticalHighlightIndicatorEnabled = true
            
            //十字线高亮颜色
            picketageSet.highlightColor = UIColor.init(hexString: "#7cb5ec")!
            
            // 是否绘制拐点
            picketageSet.drawCirclesEnabled = false
                    
            // 是否在拐点处显示数据
            picketageSet.drawValuesEnabled = true
            
            //折线点及填充色
            let color = UIColor.init(hexString: "#7cb5ec")!
            
            picketageSet.circleRadius = 5.0
            picketageSet.circleColors = [color]
            picketageSet.circleHoleRadius = 0.0
            picketageSet.drawCircleHoleEnabled = false
            
            picketageSet.setColor(color)
            picketageSet.mode = .cubicBezier
            
            picketageSet.drawIconsEnabled = true
            picketageSet.iconsOffset = .init(x: 10, y: 10)
            
            
            //渐变填充
            self.gradientFullFor(DataSet: picketageSet, andColor: color)
            
            self.lineChare.data = LineChartData.init(dataSets: [picketageSet])
            if isChange {
                self.lineChare.animate(xAxisDuration: timeInterval)
            }
        }
    }
    
    
    //MARK: - 混合分时
    /// 设置混合分时线数据
    /// - Parameter isChange: isChange description
    private func setCombineLineData (isChange:Bool = false){
        if self.arrChartData.count > 0 {
            //x、y轴数据
            var xValues = [String]()
            var yValue = [ChartDataEntry]()
            var yAveragePrice = [ChartDataEntry]()
            
            var i = 0
            for item in arrChartData {
                let _dateTime:UInt32 = item["UpdateTime"] as! UInt32
                let _strDateTime = Utils.shareInstance().getDateTimeForUnix(unixTime: _dateTime, strFormat: "HH:mm")
                xValues.append(_strDateTime)
                
                //最新价
                let entry = ChartDataEntry.init(x: Double.init(i),
                                                y: Double.init("\(item["Open"] ?? "0.000")")!)
                yValue.append(entry)
                
                //均价线(当天成交总金额除以成交总股数)
                let v = Double.init("\(item["Volume"] ?? "0.000")")!
                let c = Double.init("\(item["Close"] ?? "0.000")")!
                let entry2 = ChartDataEntry.init(x: Double.init(i),y: (c * v)/v)
                yAveragePrice.append(entry2)
                
                i += 1
            }
            
            if xValues.count > 0 {
                self.combineLineChare.xAxis.valueFormatter = IndexAxisValueFormatter.init(values: xValues)
            }
            
            //设置数据
            let data:CombinedChartData = CombinedChartData.init()
            //分时线,昨收线
            data.lineData = self.setFSDataFor(YValue: yValue,andYLastClose: yAveragePrice)
            
            self.combineLineChare.data = data
            if isChange {
                self.combineLineChare.animate(xAxisDuration: timeInterval)
            }
        }
    }
    
    private func setFSDataFor(YValue yv:[ChartDataEntry],
                              andYLastClose ylc:[ChartDataEntry]) -> LineChartData {
        //[S]分时线
        //创建LineChartDataSet对象
        let picketageSet = LineChartDataSet.init(entries: yv, label: "")
        
        //十字线
        picketageSet.drawHorizontalHighlightIndicatorEnabled = false
        picketageSet.drawVerticalHighlightIndicatorEnabled = true
        
        //十字线高亮颜色
        let color = UIColor.init(hexString: "#F0C945")!
        picketageSet.highlightColor = color
        
        //填充色
        picketageSet.circleRadius = 1.0
        picketageSet.circleColors = [color]
        picketageSet.circleHoleRadius = 2.0
        
        picketageSet.setColor(color)
        picketageSet.mode = .cubicBezier
        picketageSet.drawValuesEnabled = false
        
        //渐变填充
        self.gradientFullFor(DataSet: picketageSet, andColor: color)
        //[E]
        
        //[S]成交量线(总量/成交量)
        let picketageSet2 = LineChartDataSet.init(entries: ylc, label: "")
        picketageSet2.drawHorizontalHighlightIndicatorEnabled = false
        picketageSet2.drawVerticalHighlightIndicatorEnabled = false
        
        //填充色
        picketageSet2.circleRadius = 0.0
        picketageSet2.circleColors = [UIColor.init(hexString: "#7cb5ec")!]
        picketageSet2.circleHoleRadius = 0.0
        
        picketageSet2.setColor(UIColor.init(hexString: "#7cb5ec")!)
        picketageSet2.mode = .linear
        picketageSet2.drawValuesEnabled = false
        //[E]
        
        let lcd = LineChartData.init(dataSets: [picketageSet,picketageSet2])
        return lcd
    }
    
    
    //MARK: - 渐变填充
    /// 渐变填充
    /// - Parameters:
    ///   - ds: ds description
    ///   - c: UIColor
    private func gradientFullFor(DataSet ds:LineChartDataSet,
                                 andColor c:UIColor) {
        let gradientColors = [
            UIColor.white.cgColor,
            c.cgColor
        ]
        
        let gradient:CGGradient = CGGradient.init(colorsSpace: nil,
                                                  colors: gradientColors as CFArray,
                                                  locations: nil)!
        ds.fillAlpha = 0.65
        ds.fill = Charts.LinearGradientFill(gradient: gradient,angle: 90)
        ds.drawFilledEnabled = true
    }
}


//MARK: - ChartViewDelegate
extension MainView : ChartViewDelegate {
    
    /// 十字线滑动
    /// - Parameters:
    ///   - chartView: chartView description
    ///   - entry: entry description
    ///   - highlight: highlight description
    func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
        if self.typeIndex == 0 {
            self.xyMarkView.chartView = self.lineChare
            self.showMarkerViewFor(x: Int(entry.x),
                                   andY: String.init(format: "%.3f",entry.y))
        }
        else{
            self.xyMarkView.chartView = self.combineLineChare
            self.showMarkerViewFor2(x: Int(entry.x),
                                    andY: String.init(format: "%.3f",entry.y))
        }
    }
    
    /**
     * 设置气泡
     * https://www.hangge.com/blog/cache/detail_2125.html
     */
    func showMarkerViewFor(x:Int,andY y:String) {
        self.lineChare.drawMarkers = true
        self.lineChare.marker = self.xyMarkView
        
        if self.arrChartData.count > x {
            let _dateTime:UInt32 = self.arrChartData[x]["UpdateTime"] as! UInt32
            let _strDateTime = Utils.shareInstance().getDateTimeForUnix(unixTime: _dateTime, strFormat: "yyyy/MM/dd HH:mm")
            
            let _strInfo = String.init(format:"%@\n最新价：%@",_strDateTime,y)
            self.xyMarkView.setLabel(_strInfo)
        }
    }
    
    func showMarkerViewFor2(x:Int,andY y:String) {
        self.combineLineChare.drawMarkers = true
        self.combineLineChare.marker = self.xyMarkView
        
        if self.arrChartData.count > x {
            let _dateTime:UInt32 = self.arrChartData[x]["UpdateTime"] as! UInt32
            let _strDateTime = Utils.shareInstance().getDateTimeForUnix(unixTime: _dateTime, strFormat: "yyyy/MM/dd HH:mm")
            
            let _strInfo = String.init(format:"%@\n最新价：%@",_strDateTime,y)
            self.xyMarkView.setLabel(_strInfo)
        }
    }
}
